package com.tian.exception;

import com.tian.enums.ResultCode;
import com.tian.util.CommonResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.NoHandlerFoundException;

import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.util.Optional;

/**
 * @author tianwc  公众号：java后端技术全栈、面试专栏
 * @version 1.0.0
 * @date 2023年06月05日 16:01
 * 博客地址：<a href="http://woaijava.cc/">博客地址</a>
 * <p>
 * 统一异常处理
 * 1、自定义异常
 * 2、Http相关异常
 * 3、参数异常
 */
@RestControllerAdvice
@Slf4j
public class ChargeStationAdvice {

    @ExceptionHandler(Exception.class)
    public CommonResult<String> doException(Exception e) {

        log.error("统一异常处理机制，触发异常 msg ", e);
        String message = null;
        int errorCode = ResultCode.FAILED.getCode();
        //自定义异常
        if (e instanceof BusinessException) {
            BusinessException exception = (BusinessException) e;
            message = exception.getMessage();
            errorCode = exception.getCode();
        } else if (e instanceof HttpRequestMethodNotSupportedException) {
            message = "不支持GET/POST方法";
        } else if (e instanceof NoHandlerFoundException) {
            message = "请求接口不存在";
        } else if (e instanceof MissingServletRequestParameterException) {
            errorCode = ResultCode.PARAMETER_EMPTY.getCode();
            message = String.format("缺少必要参数[%s]", ((MissingServletRequestParameterException) e).getParameterName());
        } else if (e instanceof MethodArgumentNotValidException) {
            BindingResult result = ((MethodArgumentNotValidException) e).getBindingResult();
            FieldError error = result.getFieldError();
            errorCode = ResultCode.PARAMETER_EMPTY.getCode();
            message = error == null ? ResultCode.PARAMETER_ERROR.getMessage() : error.getDefaultMessage();
        } else if (e instanceof BindException) {
            errorCode = ResultCode.PARAMETER_EMPTY.getCode();
            message = e.getMessage();
        } else if (e instanceof ConstraintViolationException) {
            Optional<ConstraintViolation<?>> first = ((ConstraintViolationException) e).getConstraintViolations().stream().findFirst();
            errorCode = ResultCode.PARAMETER_EMPTY.getCode();
            message = first.get().getMessage();
        }
        return CommonResult.failed(errorCode, message);
    }
}
